package saxion.security.android;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

import javax.crypto.SealedObject;


import nl.saxion.security.encryption.TransformerAES;
import nl.saxion.security.synchronize.ClientSynchronize;
import nl.saxion.security.synchronize.FileIncHash;
import nl.saxion.security.synchronize.ObjectSerializer;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class SynchroniseActivity extends Activity {
	

	private ClientSynchronize clientSynchronize = null;
	private TextView logOutput;
	private TextView showIpText;
	
	private String theIP;
	
	private Button buttonSync;
	private Button buttonEncrypt;
	
	private AlertDialog encryptFilesAlert;
	private AlertDialog syncAlert;
	
	private LogReaderTask logReader;
	private TransformerAES transformer;
	
	private String FILELIST= "filelist";
	private ArrayList<FileIncHash> fileList;
	private SharedPreferences sharedPreferences;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    
	    sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
	    transformer = new TransformerAES();
	    
	    setContentView(R.layout.synctab);
        
        //find the sync button
	    buttonSync = (Button)findViewById(R.id.sync);
        buttonSync.setOnClickListener(buttonSyncOnClickListener);
        
        //find the delte button
        buttonEncrypt= (Button)findViewById(R.id.encrypt);
        buttonEncrypt.setOnClickListener(buttonEncryptOnClickListener);
        
        logOutput = (TextView)findViewById(R.id.logOutput);
        logOutput.setText("");
        
        showIpText = (TextView)findViewById(R.id.showIpText);
        
        //find the scrollview
        
        //create the alertdialog
        encryptFilesAlert = this.createEncryptFilesDialog();
        syncAlert = this.createSyncDialog();
        
		
        logReader = new LogReaderTask();
        //run the log task
        logReader.execute();
       
	}
	
	@Override
	public void onStop() {
		if(clientSynchronize != null)
			saveFileList(clientSynchronize.getFileList());
		
		logReader.cancel(true);
		super.onStop();
		
	}
	
 
	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onResume()
	 */
	protected void onResume() {

		super.onResume();
		fileList =getFileList();
		SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
	    //load the textview with the ip from settings
        theIP = sharedPreferences.getString("ipAddress", "");
        
        if(theIP.length() == 0){
        	showIpText.setText("Nog geen IP ingesteld");
        }else{
        	showIpText.setText(theIP);
        }
        
        if(clientSynchronize == null)
        	syncAlert.show();
        else
        	 clientSynchronize.setFileList(fileList);


	}
	

	/**
	 * start sync process
	 */
	Button.OnClickListener buttonSyncOnClickListener = new Button.OnClickListener(){
		public void onClick(View arg0) {
			
			clientSynchronize.setFileList(getFileList());
				if(!clientSynchronize.enableSync())
				{
					Log.e("ERROR", "Geen verbinding actief!");
				}
				
				buttonSync.setEnabled(false);
				
				while(clientSynchronize.busySync())
				{
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {

						e.printStackTrace();
					}
				}
				buttonSync.setEnabled(true);
	
		}
	};
	
	/**
	 * encrypt files in decryptfolder
	 */
	Button.OnClickListener buttonEncryptOnClickListener = new Button.OnClickListener(){
		public void onClick(View arg0) {
			buttonEncrypt.setEnabled(false);
			 try {
				 encryptDialog();
			} catch (Exception e) {
				e.printStackTrace();
			}
			buttonEncrypt.setEnabled(true);
		}
	};

	/**
	 * Dialog showed when user clicks on the "encrypt all files button"
	 */
	private void encryptDialog(){
			
		//prefs
		final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SynchroniseActivity.this);		 
		final String decryptedFolderLocation = prefs.getString("decryptedFolderLocation", "");
		
		//filedir
		File dir = new File(decryptedFolderLocation);
		final File[] files = dir.listFiles();
		
		Log.v("FILESLENGHT", "filelength " + files.length );
		
		if(files.length > 0){
			 // This example shows how to add a custom layout to an AlertDialog
		   
			encryptFilesAlert.show();
		}else{
			Context context = getApplicationContext();
			int duration = Toast.LENGTH_SHORT;
			Toast toast = Toast.makeText(context, R.string.encrypt_no_files, duration);
			toast.show();
		}
	}
	 
	/**
	 * Encrypts all the files in the decryptedFolder
	 * @param pwInput, the password 
	 */
	private void encryptAllFiles(EditText pwInput){
		 
	 	//load al the variables from the preferences     
	final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SynchroniseActivity.this);
	final String encryptedFolderLocation = prefs.getString("encryptedFolderLocation", "");
	final String decryptedFolderLocation = prefs.getString("decryptedFolderLocation", "");
	
	
	
	File dir = new File(decryptedFolderLocation);
	final File[] files = dir.listFiles();
			
	try {
		ArrayList<FileIncHash> newEncyptedFiles = clientSynchronize.encryptFiles(files, encryptedFolderLocation);
	
		//fileList = getFileList();
		
		//fileList.addAll(newEncyptedFiles); //new filelist!
		clientSynchronize.setFileList(newEncyptedFiles); //save to sync
		
		saveFileList(clientSynchronize.getFileList()); //save to config..
		
		Context context = getApplicationContext();
		int duration = Toast.LENGTH_SHORT;
		String msg = getString(R.string.encrypt_toast_all);
		Toast toast = Toast.makeText(context, ""+ msg  + " ("+files.length+")", duration);
		toast.show();
		
		//update file list
	   // saveFileList( trans.addFiles(fileList, newEncyptedFiles, encryptedFolderLocation));
		
	} catch (Exception e) {
		//false key
		Context context = getApplicationContext();
		int duration = Toast.LENGTH_SHORT;
		Toast toast = Toast.makeText(context, R.string.password_toast_wrong, duration);
		toast.show();
	}
	
	//loader.dismiss();
			
	}
	
	 @SuppressWarnings("unchecked")
	/**
	 * Gets the file list from the preferences
	 * @return ArrayList with all the files
	 */
	private ArrayList<FileIncHash> getFileList()
	 {
		 SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
		 ArrayList<FileIncHash> fileList = null;
			try {
				fileList = (ArrayList<FileIncHash>)ObjectSerializer.deserialize(sharedPreferences.getString(FILELIST, ObjectSerializer.serialize(new ArrayList<FileIncHash>())));
			} catch (IOException e) {

				e.printStackTrace();
			}
		return fileList;
	 }
	/**
	 * Sets the file list to the preferences
	 */
	private void saveFileList(ArrayList<FileIncHash> newFiles)
	{
		fileList = newFiles;
		SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
		SharedPreferences.Editor editor = sharedPreferences.edit();
		try {
			editor.putString(FILELIST, ObjectSerializer.serialize(newFiles));
			  editor.commit(); 
		} catch (IOException e) {
		
			e.printStackTrace();
		}
	}

	/**
	 * Dialog to encrypt the files
	 * @return AlertDialog
	 */
	private AlertDialog createEncryptFilesDialog(){
		AlertDialog dialog = null;
		 
	 	LayoutInflater factory = LayoutInflater.from(this);
	    final View textEntryView = factory.inflate(R.layout.insertpw_dialog, null);
	    Builder alertBuilder = new AlertDialog.Builder(SynchroniseActivity.this);
	    alertBuilder.setTitle(R.string.password_dialog_title);
	    alertBuilder.setView(textEntryView);
	    alertBuilder.setPositiveButton("Encrypten", new DialogInterface.OnClickListener() {
	        public void onClick(DialogInterface dialog, int whichButton) {
	        	EditText pwInput = (EditText) textEntryView.findViewById(R.id.passwordFileOpen);
	        	
	        	dialog.dismiss();
	    		ProgressDialog loader = ProgressDialog.show(SynchroniseActivity.this, "", "Encrypten. Please wait...", true);
	    		loader.show();
	        	
	        	encryptAllFiles(pwInput);
	        	loader.dismiss();
	        	
	        }
	  	});
	    alertBuilder.setNegativeButton("Annuleren", new DialogInterface.OnClickListener() {
	        public void onClick(DialogInterface dialog, int whichButton) {
	
	
	        }
	    });
	    dialog = alertBuilder.create();
	    return dialog;
	}
	
	/**
	 * Dialog to set up the sync
	 * @return AlertDialog
	 */
	private AlertDialog createSyncDialog(){
		AlertDialog dialog = null;
		 
	 	LayoutInflater factory = LayoutInflater.from(this);
        final View textEntryView = factory.inflate(R.layout.sync_dialog, null);
        Builder alertBuilder = new AlertDialog.Builder(SynchroniseActivity.this);
        alertBuilder.setTitle(R.string.password_dialog_title);

        //load the view with the ip
        Log.v("IP", "the ip " +theIP);
        EditText ip = (EditText) textEntryView.findViewById(R.id.syncIP);
        EditText pwInput = (EditText) textEntryView.findViewById(R.id.syncPassword);
        
        pwInput.requestFocus();
        ip.setText(sharedPreferences.getString("ipAddress", ""));
        theIP = sharedPreferences.getString("ipAddress", "");
      
        alertBuilder.setView(textEntryView);
        alertBuilder.setPositiveButton("Ontgrendelen", new DialogInterface.OnClickListener() {
        	
            public void onClick(DialogInterface dialog, int whichButton) {
            	EditText pwInput = (EditText) textEntryView.findViewById(R.id.syncPassword);
            	EditText ip = (EditText) textEntryView.findViewById(R.id.syncIP);
            	
            	String ipString = ip.getText().toString();
            	String pwInputString = pwInput.getText().toString();
            	
            	theIP = ipString;
            	
            	//save the ip
            	SharedPreferences.Editor editor = sharedPreferences.edit(); //set the preferences in edit mode
				editor.putString("ipAddress", theIP);
		        editor.commit();
            	
		        //show the ip in the textview
		        showIpText.setText(theIP);
            	byte[] pwdHash = null;
				try {
					pwdHash = transformer.generateKey(pwInputString);
				} catch (Exception e) {
					e.printStackTrace();
				}
            	//generate pwd;
            	boolean newSync= false;
				if(clientSynchronize == null){
				
				
	        	SealedObject sealedKey = null;
				
					try {
						sealedKey = (SealedObject)ObjectSerializer.deserialize(sharedPreferences.getString("sealedKey", ""));
					} catch (IOException e) {
						e.printStackTrace();
					}
				clientSynchronize = new ClientSynchronize(sharedPreferences.getString("encryptedFolderLocation", ""), theIP, fileList, sealedKey, null);
				 //clientSynchronize.setFileList(fileList);
				 
				 newSync = true;
				}
				clientSynchronize.setPassword(pwdHash);
				
				if(newSync){
					clientSynchronize.start();
				}
            }
      	});
        alertBuilder.setNegativeButton("Annuleren", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {


            }
        });
        dialog = alertBuilder.create();
        return dialog;
	}
	 
	
	 private class LogReaderTask extends AsyncTask<Void, String, Void>
	 {

            private final int BUFFER_SIZE = 1024;
            
            private boolean isRunning = true;
            private Process logprocess = null;
            private BufferedReader reader = null;
            private String[] line = null;
            
            
            @Override
            protected Void doInBackground(Void... params) {
                    try {
                    		//process = Runtime.getRuntime().exec("logcat -d -v raw System.out:I *:S");
                            logprocess = Runtime.getRuntime().exec("logcat -s raw System.out");
                           
                    } catch (IOException e) {
                            e.printStackTrace();
                            
                            isRunning = false;
                    }
                    
                    try {
                            reader = new BufferedReader(new InputStreamReader(logprocess.getInputStream()),BUFFER_SIZE);
                    }
                    catch(IllegalArgumentException e){
                            e.printStackTrace();
                            
                            isRunning = false;
                    }
                    
                    line = new String[1];
                    
                    try {
                            while(isRunning == true)
                            {
                            	if(isRunning && !reader.equals(null))
                                    line[0] = reader.readLine();
                                    String[] temp;
                                    temp = line[0].split("\\:");
                                    
                                    for(int i =0; i < temp.length ; i++){
                                    	if(i == 1){
                                    	  publishProgress(temp[i]);
                                    	}
                            		}	
                                    //int item = 1;
                                   // publishProgress("test" + temp[1]);
                                    //publishProgress(line);
                            }
                    } 
                    catch (IOException e) {
                            e.printStackTrace();
                            
                            isRunning = false;
                    }
                    
                    return null;
            }
    
            @Override
            protected void onCancelled() {
                    super.onCancelled();
            }
            
            @Override
            protected void onPreExecute() {
                    super.onPreExecute();
                    logOutput.setText("");
            }
            
            @Override
            protected void onPostExecute(Void result) {
                    super.onPostExecute(result);
            }
            
            @Override
            protected void onProgressUpdate(String... values) {
                    super.onProgressUpdate(values);
                    
                    logOutput.setText(logOutput.getText() + "\n" + values[0].toString());
                    //logOutput.append(values[0].toString() + "\n");
            }
            /*
            public void stopTask(){
                    isRunning = false;
                    logprocess.destroy();                   
            }
            */
	    }
	


}
